#include "app_buffer.h"
#include <stdlib.h>
#include <string.h>
#include "log/log.h"
//初始化生成小缓冲区
SubBuffer *sub_buffer_init(int size)
{
    //申请内存
    SubBuffer *sub_buffer = (SubBuffer *)malloc(sizeof(SubBuffer));
    //初始化
    sub_buffer->len = 0;
    sub_buffer->ptr = (char *)malloc(size);
    sub_buffer->size = size;
    return sub_buffer;
}

Buffer *app_buffer_init(int size)
{
    //申请内存
    Buffer *buffer = (Buffer *)malloc(sizeof(Buffer));
    //初始化
    buffer->sub_buffers[0] = sub_buffer_init(size);
    buffer->sub_buffers[1] = sub_buffer_init(size);

    buffer->write_index = 1;
    buffer->read_index = 0;

    //初始化读写锁
    pthread_mutex_init(&buffer->read_lock, NULL);
    pthread_mutex_init(&buffer->write_lock, NULL);
    return buffer;
}

void app_buffer_destroy(Buffer *buffer)
{
    free(buffer->sub_buffers[0]->ptr);
    free(buffer->sub_buffers[0]);
    free(buffer->sub_buffers[1]->ptr);
    free(buffer->sub_buffers[1]);
    free(buffer);
}

int app_buffer_write(Buffer *buffer, char *data, int len)
{
    //判断数据长度是否合法，不能超过255 ，只有一个字节存储len
    if (len > 255)
    {
        log_error("数据长度不合法, 不能超过255");
        return -1;
    }
    //加写锁
    log_debug("加写锁");
    pthread_mutex_lock(&buffer->write_lock);

    //获取写入的子缓冲区
    SubBuffer *w_buffer = buffer->sub_buffers[buffer->write_index];
    //判断剩余空间是否充足
    if (w_buffer->size - w_buffer->len < len + 1)
    {
        log_error("buffer剩余空间不足");
        //释放写锁
        log_debug("释放写锁");
        pthread_mutex_unlock(&buffer->write_lock);
        return -1;
    }
    //向子缓冲区中写入数据和长度
    w_buffer->ptr[w_buffer->len] = len;
    memcpy(w_buffer->ptr + w_buffer->len + 1, data, len);
    //更新子缓冲区中的长度
    w_buffer->len += len + 1;
    //释放写锁
    log_debug("释放写锁");
    pthread_mutex_unlock(&buffer->write_lock);
    return 0;
}
 static void swap_sub_buffer(Buffer *buffer)
 {
    //加写锁
    log_debug("在交换子缓冲区时加写锁");
    pthread_mutex_lock(&buffer->write_lock);
     buffer->write_index = (buffer->write_index + 1) % 2;
     buffer->read_index = (buffer->read_index + 1) % 2;
     //解写锁
     log_debug("在交换子缓冲区后释放写锁");
     pthread_mutex_unlock(&buffer->write_lock);
 }
int app_buffer_read(Buffer *buffer, char *data_buf, int buf_len)
{
    //加读锁
    log_debug("加读锁");
    pthread_mutex_lock(&buffer->read_lock);
    //获取读取的子缓冲区
    SubBuffer *r_buffer = buffer->sub_buffers[buffer->read_index];
    //判断子缓冲区是否为空,为空则切换子缓冲区
    if (r_buffer->len == 0)
    {
        swap_sub_buffer(buffer);
        r_buffer = buffer->sub_buffers[buffer->read_index];
        //如果交换后子缓冲区还是为空，则返回-1
        if (r_buffer->len == 0)
        {
            log_error("buffer为空");
            //释放读锁
            log_debug("释放读锁");
            pthread_mutex_unlock(&buffer->read_lock);
            return -1;
        }
    }
    //读取数据长度
    int len = r_buffer->ptr[0];
    //判断容器大小是否充足
    if (len > buf_len)
    {
        //释放读锁
        log_debug("释放读锁");
        pthread_mutex_unlock(&buffer->read_lock);
        log_error("容器大小不足");
        return -1;
    }
    //获取数据长度对应数据，保存到data_buf中
    memcpy(data_buf, r_buffer->ptr + 1, len);
    // 移动读取索引，将未读取的数据移动到起始位置
    memmove(r_buffer->ptr, r_buffer->ptr + len + 1, r_buffer->size - len - 1);
    //更新子缓冲区中的长度
    r_buffer->len -= len + 1;
    //释放读锁
    log_debug("释放读锁");
    pthread_mutex_unlock(&buffer->read_lock);
    // 返回读取的长度
    return  len;
}
